The DateTimePicker control is a text box especially designed for Date or Time values. The text box is subdivided into subfields, one for each individual component (day, month, year, hour, minute, and second). This control supports all the usual date and time formats (including a custom format) and the ability to return a Null value (if the user doesn't want to select a particular date). You can even define your own custom subfields.
At run time, end users can advance through subfields using the Left and Right arrow keys and can increment and decrement their values using the Up and Down arrow keys. They can display a drop-down calendar (if the UpDown property is set to False) or modify the current value of the highlighted component using the companion spin buttons (if the value of UpDown is True).
By default, a Down arrow appears to the right of the control, much like a regular ComboBox control: A click on the arrow drops down a calendar, which lets users select a date without typing any keys. If you set the UpDown property to True, however, the Down arrow is replaced by a pair of spin buttons, which let users increment or decrement the value of individual subfields using only the mouse.
The CheckBox property, if True, displays a check box near the left border of the control: Users can deselect this check box if they don't intend to actually select any dates. (See Figure 11-7.)
The DateTimePicker control shares a few properties with the MonthView control. For example, it exposes a Value property, which returns the Date value entered by the end user, and the MinDate and MaxDate properties, which define the interval of valid dates.
The drop-down calendar is nothing but a MonthView control that can show only one month at a time. Thus, the DateTimePicker control also exposes all the color properties of the MonthView control, even though each now has a different name: CalendarForeColor, CalendarBackColor, CalendarTitleForeColor, CalendarTitleBackColor, and CalendarTrailingForeColor. Oddly, the control doesn't expose the standard ForeColor and BackColor properties, so while you can modify the appearance of the drop-down calendar, you can't programmatically change the default colors of the edit portion of the control!
The Format property affects what's displayed in the control and can be one of the following values: 0-dtpLongDate, 1-dtpShortDate, 2-dtpTime, or 3-dtpCustom. If you select a custom format, you can assign a suitable string to the CustomFormat property. This property accepts the same formatting strings that you would pass to a Format function that works with date or time values. You can use this string:
'Date is' dddd MMM d, yyy |
to display a value such as
Date is Friday Nov 5, 1999 |
As you see, you can include literal strings by enclosing them within single quotation marks. As I'll explain in a moment, the CustomFormat property can be used to create custom subfields too.
Figure 11-7. Different styles of the DateTimePicker control.
The DateTimePicker control can be bound to a data source, so it exposes the usual DataSource, DataMember, DataField, and DataFormat properties. The DataFormat property isn't supported when the control is bound to a standard Data or RemoteData control, but in either case you can modify the format of the displayed value using the Format and CustomFormat properties.
At run time, you set and retrieve the contents in the DateTimePicker control through the Value property or by means of the Year, Month, Day, DayOfWeek, Hour, Minute, and Second properties. For example, you can programmatically increment the month portion of a date displayed in a DateTimePicker control with the following statements:
DTPicker1.Month = (DTPicker1.Month Mod 12) + 1 If DTPicker1.Month = 1 Then DTPicker1.Year = DTPicker1.Year + 1 |
If CheckBox is True and the user has deselected the check box, all date-related properties return Null.
The DateTimePicker control exposes many of the events supported by a standard TextBox control, including Change, KeyDown, KeyPress, KeyUp, MouseDown, MouseMove, MouseUp, Click, and DblClick. All keyboard and mouse events refer to the edit portion of the control and so don't fire when a calendar has been dropped down.
When the user clicks on the Down arrow, a DropDown event fires just before the drop-down calendar actually appears—that is, if the UpDown property is False (the default value). When the user selects a date in the drop-down calendar, a CloseUp event fires. These events aren't particularly useful, however, because you don't have much control over the calendar itself, apart from the colors it uses. When the user selects a date in the drop-down calendar, the Change event fires before the CloseUp event.
CAUTION
Because of a bug in the DateTimePicker control, you can't assign both the MinDate and MaxDate properties at run time. When you assign either one, the other is assigned the date 12/31/1999. The reason for this odd behavior and a possible workaround are explained in article Q198880 of Microsoft Knowledge Base.
The most intriguing feature of the DateTimePicker control is the capability to define custom subfields, also known as callback fields. To define a callback field, you use a string of one or more X characters in the value assigned to the CustomFormat property. You can define multiple callback fields by using strings with different numbers of Xs. For example, the following format defines a date field with two callback fields:
DTPicker1.CustomFormat = "MMM d, yyy '(week 'XX')' XXX" |
In the code sample that follows, the XX field is defined as the number of weeks since January 1, and the XXX field is the name of the holiday, if any, that occurs on the displayed date.
When you define a callback field, you're in charge of defining its maximum length, its current value, and its behavior (that is, what happens if the user presses a key when the caret is on it). You establish the maximum size of a callback field in the FormatSize custom event, which fires once for each callback field. If you have multiple fields, you must prepare a Select Case structure, as in the following code:
Private Sub DTPicker1_FormatSize(ByVal CallbackField As String, _ Size As Integer) Select Case CallbackField Case "XX" ' The number of weeks since January 1st (max 2 digits) Size = 2 Case "XXX" ' The name of a holiday, if any Size = 16 End Select End Sub |
When the DateTimePicker control is about to display a date, it raises a Format event for each callback field. You return the value of the callback field in the FormattedString parameter:
Private Sub DTPicker1_Format(ByVal CallbackField As String, _ FormattedString As String) Select Case CallbackField Case "XX" ' The number of weeks since January 1st (max 2 digits) FormattedString = DateDiff("ww", _ DateSerial(DTPicker1.Year, 1, 1), DTPicker1.Value) Case "XXX" ' The name of a holiday, if any If DTPicker1.Month = 12 And DTPicker1.Day = 25 Then FormattedString = "Christmas" Else ' Deal here with other holidays. End If End Select End Sub |
You can process all the keys pressed when the caret is on a callback field by writing code in the CallbackKeyDown event procedure. This event receives information about the key being pressed, the state of shift keys, and the name of the callback field. Typically, you process the key by assigning a new Date value to the CallbackDate parameter:
Private Sub DTPicker1_CallbackKeyDown(ByVal KeyCode As Integer, _ ByVal Shift As Integer, ByVal CallbackField As String, _ CallbackDate As Date) If CallbackField = "XX" Then ' Move to the previous/next week when the Up/Down key is pressed. If KeyCode = vbKeyUp Then CallbackDate = DTPicker1.Value + 7 ElseIf KeyCode = vbKeyDown Then CallbackDate = DTPicker1.Value - 7 End If Else ' No keyboard support for the Holiday field End If End Sub |